package com.yxuan.springboot.util;

import com.alibaba.fastjson.JSONObject;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Base64;


@Component
@Slf4j
public class WxPayUtil {

    public static final String mchId = "1677335562"; // 商户号

    public static final String appId = "wx192f019efa82b221"; // appId

    public static final String apiV3Key = "8yG5BM2mWyYhQqN27RdhCmvqwWcgYZMk"; // apiV3秘钥
    //商户私钥路径
    public static final String privateKeyUrl = "cert/apiclient_key.pem";
//    public static final String privateKeyUrl = "E:\项目开发\教育平台\微信支付证书\apiclient_key.pem";
    //平台证书路径
    public static final String wechatPayCertificateUrl = "cert/wechatpay_4331BB8F5230A34D4B789A208670EFC9D4BB779F.pem";
//    public static final String wechatPayCertificateUrl = "D:/plugins/wechatpay_4331BB8F5230A34D4B789A208670EFC9D4BB779F.pem";
//    public static final String wechatPayCertificateUrl = "D:\plugins\wechatpay_4331BB8F5230A34D4B789A208670EFC9D4BB779F.pem";


//    public static final String wechatPayCertificateUrl = "E:\项目开发\教育平台\微信支付证书\\wechatpay_6F485D9851DDB99028A66D413940CAF2C9C7763E.pem";
    //第一步申请完证书后，在API证书哪里点击管理证书就能看到
   public static final String mchSerialNo = "69EED795F0A1B26F35B8A72C498F7609248EA256"; // 商户证书序列号

    private CloseableHttpClient httpClient;



    public void setup()  {
     //   PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(privateKey);
        PrivateKey merchantPrivateKey = null;
        X509Certificate wechatPayCertificate = null;

        try {
            merchantPrivateKey = PemUtil.loadPrivateKey(
                    new FileInputStream(privateKeyUrl));
            wechatPayCertificate = PemUtil.loadCertificate(
                    new FileInputStream(wechatPayCertificateUrl));

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        ArrayList<X509Certificate> listCertificates = new ArrayList<>();
        listCertificates.add(wechatPayCertificate);
        WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
                .withMerchant(mchId, mchSerialNo, merchantPrivateKey)
                .withWechatPay(listCertificates);
        httpClient = builder.build();
    }

    /**
     * wxMchid商户号
     * wxCertno证书编号
     * wxCertPath证书地址
     * wxPaternerKey   v3秘钥
     * url 下单地址
     * body 构造好的消息体
     */
    public JSONObject doPostWexinV3(String url, String body,String indentid) {
        if (httpClient == null) {
            setup();
        }

        HttpPost httpPost = new HttpPost(url);
        httpPost.addHeader("Content-Type", "application/json;chartset=utf-8");
        httpPost.addHeader("Accept", "application/json");
        try {
            if (body == null) {
                throw new IllegalArgumentException("data参数不能为空");
            }
            StringEntity stringEntity = new StringEntity(body, "utf-8");
            httpPost.setEntity(stringEntity);
            // 直接执行execute方法，官方会自动处理签名和验签，并进行证书自动更新
            HttpResponse httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();

            if (httpResponse.getStatusLine().getStatusCode() == 200) {
                String jsonResult = EntityUtils.toString(httpEntity);
                return JSONObject.parseObject(jsonResult);
            } else {
                System.err.println("微信支付错误信息" + EntityUtils.toString(httpEntity));
                // 发送邮件通知


            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;

    }

    public JSONObject doGetWexinV3(String url) {
        if (httpClient == null) {
            setup();
        }
        HttpGet httpGet = new HttpGet(url);
//        HttpPost httpPost = new HttpPost(url);
        httpGet.addHeader("Content-Type", "application/json;chartset=utf-8");
        httpGet.addHeader("Accept", "application/json");
        try {
//            if (body == null) {
//                throw new IllegalArgumentException("data参数不能为空");
//            }
            StringEntity stringEntity = new StringEntity("utf-8");
//            httpGet.setEntity(stringEntity);
            // 直接执行execute方法，官方会自动处理签名和验签，并进行证书自动更新
            HttpResponse httpResponse = httpClient.execute(httpGet);
            HttpEntity httpEntity = httpResponse.getEntity();

            if (httpResponse.getStatusLine().getStatusCode() == 200) {
                String jsonResult = EntityUtils.toString(httpEntity);
                return JSONObject.parseObject(jsonResult);
            } else {
                System.err.println("微信支付错误信息" + EntityUtils.toString(httpEntity));
                // 发送邮件通知

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;

    }

    //获取签名
    public String getSign(String appId, long timestamp, String nonceStr, String pack){
        String message = buildMessage(appId, timestamp, nonceStr, pack);
        System.out.println(message);
        String paySign= null;
        try {
            paySign = sign(message.getBytes("utf-8"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return paySign;
    }

    //获取签名2
//    public String getSign2(String appId, String mch_id, String out_trade_no, String nonce_str){
//        String message = buildMessage2(appId, mch_id, out_trade_no, nonce_str);
//        String paySign= null;
//        try {
//            paySign = sign(message.getBytes("utf-8"));
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        return paySign;
//    }

    private String buildMessage(String appId, long timestamp, String nonceStr, String pack) {
        return appId + "\n"
                + timestamp + "\n"
                + nonceStr + "\n"
                + pack + "\n";
    }

    private String buildMessage2(String appId, String mch_id, String out_trade_no, String nonce_str) {
        return appId + "\n"
                + mch_id + "\n"
                + out_trade_no + "\n"
                + nonce_str + "\n";
    }

    private String sign(byte[] message) throws Exception{
        PrivateKey merchantPrivateKey = null;
        X509Certificate wechatPayCertificate = null;

        try {
            merchantPrivateKey = PemUtil.loadPrivateKey(
                    new FileInputStream(privateKeyUrl));
            wechatPayCertificate = PemUtil.loadCertificate(
                    new FileInputStream(wechatPayCertificateUrl));

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        Signature sign = Signature.getInstance("SHA256withRSA");
        //这里需要一个PrivateKey类型的参数，就是商户的私钥。
        sign.initSign(merchantPrivateKey);
        sign.update(message);
        return Base64.getEncoder().encodeToString(sign.sign());
    }


}